<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-horizon" tabindex="-1"><a class="header-anchor" href="#laravel-horizon"><span>Laravel Horizon</span></a></h2>
<ul>
<li><a href="#introduction">介绍</a></li>
<li><a href="#installation">安装</a>
<ul>
<li><a href="#configuration">配置</a></li>
<li><a href="#balancing-strategies">均衡策略</a></li>
<li><a href="#dashboard-authorization">仪表盘授权</a></li>
<li><a href="#silenced-jobs">静默任务</a></li>
</ul>
</li>
<li><a href="#upgrading-horizon">升级 Horizon</a></li>
<li><a href="#running-horizon">运行 Horizon</a>
<ul>
<li><a href="#deploying-horizon">部署 Horizon</a></li>
</ul>
</li>
<li><a href="#tags">标签</a></li>
<li><a href="#notifications">通知</a></li>
<li><a href="#metrics">指标</a></li>
<li><a href="#deleting-failed-jobs">删除失败的任务</a></li>
<li><a href="#clearing-jobs-from-queues">从队列中清除任务</a></li>
</ul>
<h2 id="介绍" tabindex="-1"><a class="header-anchor" href="#介绍"><span>介绍</span></a></h2>
<blockquote>
<p><strong>提示</strong><br>
在深入了解 Laravel Horizon 之前，你应该熟悉 Laravel 的基础 <a href="https://learnku.com/docs/laravel/11.x/queues" target="_blank" rel="noopener noreferrer">队列服务</a>。 Horizon 为 Laravel 的队列增加了额外的功能，如果你还不熟悉 Laravel 提供的基本队列功能，这些功能可能会让你感到困惑。</p>
</blockquote>
<p><a href="https://github.com/laravel/horizon" target="_blank" rel="noopener noreferrer">Laravel Horizon</a> 为你的 Laravel <a href="https://learnku.com/docs/laravel/11.x/queues" target="_blank" rel="noopener noreferrer">Redis queues</a> 提供了一个美观的仪表盘和代码驱动的配置。它可以方便地监控队列系统的关键指标：任务吞吐量、运行时间、任务失败情况。</p>
<p>在使用 Horizon 时，所有队列的 worker 配置都存储在一个简单的配置文件中。通过在受版本控制的文件中定义应用程序的 worker 配置，你可以在部署应用程序时轻松扩展或修改应用程序的队列 worker。</p>
<p><img src="https://laravel.com/img/docs/horizon-example.png" alt="horizon-example.png"></p>
<h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装"><span>安装</span></a></h2>
<blockquote>
<p><strong>警告</strong><br>
Laravel Horizon 要求你使用 <a href="https://redis.io/" target="_blank" rel="noopener noreferrer">Redis</a> 来加强你的队列。因此，你应该确保在应用程序的 <code v-pre>config/queue.php</code> 配置文件中将队列连接设置为 <code v-pre>redis</code>。</p>
</blockquote>
<p>你可以使用 Composer 包管理工具将 Horizon 安装到你的项目里：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> require laravel/horizon</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>Horizon 安装之后，使用 <code v-pre>horizon:install</code> Artisan 命令发布资源：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:install</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h3>
<p>Horizon 资源发布之后，其主要配置文件将位于 <code v-pre>config/horizon.php</code> 文件中。此配置文件允许你为应用程序配置队列 worker 选项。每个配置选项包含其用途的描述，所以请务必仔细研究这个文件。</p>
<blockquote>
<p><strong>警告</strong><br>
Horizon 在内部使用名为 <code v-pre>horizon</code> 的 Redis 连接。此 Redis 连接名称是保留的，不应再分配给 <code v-pre>database.php</code> 配置文件中的另一个 Redis 连接，也不可作为 <code v-pre>horizon.php</code> 配置文件中的 <code v-pre>use</code> 选项的值。</p>
</blockquote>
<h4 id="环境" tabindex="-1"><a class="header-anchor" href="#环境"><span>环境</span></a></h4>
<p>安装完成后，你应该熟悉的主要 Horizon 配置选项是 <code v-pre>environments</code> 配置选项。此配置选项是一个数组，包含了你的应用程序运行的环境，并为每个环境定义了 worker 进程选项。默认情况下，此条目包含一个 <code v-pre>production</code> 和 一个 <code v-pre>local</code> 环境。不过，你可以根据自己需要自由添加更多环境：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'environments'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'production'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'supervisor-1'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'maxProcesses'</span> <span class="token operator">=></span> <span class="token number">10</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'balanceMaxShift'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'balanceCooldown'</span> <span class="token operator">=></span> <span class="token number">3</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'local'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'supervisor-1'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'maxProcesses'</span> <span class="token operator">=></span> <span class="token number">3</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以定义一个通配符环境（<code v-pre>*</code>），当找不到其他匹配的环境时将使用该环境：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'environments'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'*'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'supervisor-1'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'maxProcesses'</span> <span class="token operator">=></span> <span class="token number">3</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当你启动 Horizon 时，它将使用应用程序运行环境所配置的 worker 进程选项。通常情况下，环境由 <code v-pre>APP_ENV</code> <a href="https://learnku.com/docs/laravel/11.x/configuration#determining-the-current-environment" target="_blank" rel="noopener noreferrer">环境变量</a> 的值决定。例如，默认的 <code v-pre>local</code> Horizon 环境配置为启动三个 worker 进程，并自动平衡分配给每个队列的 worker 进程数量。默认的 <code v-pre>production</code> 环境配置为最多启动 10 个 worker 进程，并自动平衡分配给每个队列的 worker 进程数量。</p>
<blockquote>
<p><strong>警告</strong><br>
你应该确保你的 <code v-pre>horizon</code> 配置文件的 <code v-pre>environments</code> 部分包含计划在其上运行 Horizon 的每个 <a href="https://learnku.com/docs/laravel/11.x/configuration#environment-configuration" target="_blank" rel="noopener noreferrer">环境</a> 的配置。</p>
</blockquote>
<h4 id="supervisors" tabindex="-1"><a class="header-anchor" href="#supervisors"><span>Supervisors</span></a></h4>
<p>正如你在 Horizon 的默认配置文件中看到的那样，每个环境可以包含一个或多个 Supervisor 配置。默认情况下，配置文件将这个 Supervisor 定义为 <code v-pre>supervisor-1</code>；但是，你可以随意命名你的 Supervisor。每个 Supervisor 负责「监督」一组 worker 进程，并负责平衡队列之间的 worker 进程。</p>
<p>如果你想定义一组在指定环境中运行的新 worker 进程，可以向相应的环境添加额外的 Supervisor。如果你想为应用程序使用的特定队列定义不同的平衡策略或 worker 数量，也可以选择这样做。</p>
<h4 id="维护模式" tabindex="-1"><a class="header-anchor" href="#维护模式"><span>维护模式</span></a></h4>
<p>当你的应用进入维护模式<a href="https://learnku.com/docs/laravel/11.x/configurationmd#maintenance-mode" target="_blank" rel="noopener noreferrer">维护模式</a>，除非 Horizon 配置文件中对应 supervisor 的 <code v-pre>force</code> 配置项被定义为 <code v-pre>true</code>， 否则 Horizion 将无法执行队列任务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token string single-quoted-string">'environments'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'production'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'supervisor-1'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token comment">// ...</span></span>
<span class="line">                <span class="token string single-quoted-string">'force'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="默认值" tabindex="-1"><a class="header-anchor" href="#默认值"><span>默认值</span></a></h4>
<p>在 Horizon 的默认配置文件中，你会注意到一个 <code v-pre>defaults</code> 配置选项。<br>
这个配置选项指定应用程序的 <a href="#supervisors">supervisors</a> 的默认值。Supervisor 的默认配置值将合并到每个环境的 Supervisor 配置中，让你在定义 Supervisor 时避免不必要的重复工作。</p>
<h3 id="均衡策略" tabindex="-1"><a class="header-anchor" href="#均衡策略"><span>均衡策略</span></a></h3>
<p>与 Laravel 的默认队列系统不同，Horizon 允许你从三个平衡策略中进行选择：<code v-pre>simple</code>， <code v-pre>auto</code>， 和 <code v-pre>false</code>。<code v-pre>simple</code> 策略会在进程之间均匀分配进入的任务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token string single-quoted-string">'balance'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'simple'</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>配置文件默认的 <code v-pre>auto</code> 策略根据队列的当前工作负载来调整每个队列的工作进程数量。例如，如果你的 <code v-pre>notifications</code> 队列有 1000 个等待种的任务，而你的 <code v-pre>render</code> 队列是空的，那么 Horizon 将为 <code v-pre>notifications</code> 队列分配更多的 Worker 进程，直到队列为空。</p>
<p>当使用 <code v-pre>auto</code> 策略时，你可以定义 <code v-pre>minProcesses</code> 和 <code v-pre>maxProcesses</code> 的配置选项来控制 Horizon 的 Woker 进程最小和最大数量：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token string single-quoted-string">'environments'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'production'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'supervisor-1'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'connection'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'redis'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'queue'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'default'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'balance'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'auto'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'autoScalingStrategy'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'time'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'minProcesses'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'maxProcesses'</span> <span class="token operator">=></span> <span class="token number">10</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'balanceMaxShift'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'balanceCooldown'</span> <span class="token operator">=></span> <span class="token number">3</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'tries'</span> <span class="token operator">=></span> <span class="token number">3</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>autoScalingStrategy</code> 配置值决定了 Horizon 分配更多 Worker 进程到队列是基于清空队列的总时长（<code v-pre>time</code> 策略）还是队列中任务的总数量（<code v-pre>size</code> 策略）。</p>
<p><code v-pre>balanceMaxShift</code> 和 <code v-pre>balanceCooldown</code> 配置项可以决定 Horizon 将以多快的速度扩展进程。在上面的示例中，每秒钟最多创建一个新的进程，或每 3 秒钟最多销毁一个进程，你可以根据应用程序的需要随意调整这些值。</p>
<p>当 <code v-pre>balance</code> 选项设置为 <code v-pre>false</code> 时，将使用默认的 Laravel 行为，它按照队列在配置中列出的顺序处理队列。</p>
<h3 id="控制面板授权" tabindex="-1"><a class="header-anchor" href="#控制面板授权"><span>控制面板授权</span></a></h3>
<p>Horizon 在 <code v-pre>/horizon</code> 上显示了一个控制面板。默认情况下，你只能在 <code v-pre>local</code> 环境中访问这个面板。在你的 <code v-pre>app/Providers/HorizonServiceProvider.php</code> 文件中，有一个 <a href="https://learnku.com/docs/laravel/11.x/authorizationmd#gates" target="_blank" rel="noopener noreferrer">授权拦截器（Gates）</a> 的方法定义。该拦截器用于控制在<strong>非本地</strong>环境中对 Horizon 的访问。你可以根据需要修改此方法，来限制对 Horizon 的访问：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册 Horizon 守门逻辑。</span>
<span class="line">     *</span>
<span class="line">     * 该守门逻辑决定谁可以在非本地环境下访问 Horizon。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">gate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'viewHorizon'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token function">in_array</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'taylor@laravel.com'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="可替代的身份验证策略" tabindex="-1"><a class="header-anchor" href="#可替代的身份验证策略"><span>可替代的身份验证策略</span></a></h4>
<p>需要留意的是，Laravel 会自动将经过认证的用户注入到拦截器（Gate）闭包中。如果你的应用程序通过其他方法提供 Horizon 安全性保障，例如 IP 限制，那么你访问 Horizon 用户可能不需要实现这个「登录」动作。因此，你需要将上面的 <code v-pre>function (User $user)</code> 更改为 <code v-pre>function (User $user = null)</code> 以强制 Laravel 不必进行身份验证。</p>
<h3 id="静默任务" tabindex="-1"><a class="header-anchor" href="#静默任务"><span>静默任务</span></a></h3>
<p>有时，你可能对查看某些由你的应用程序或第三方软件包发出的工作不感兴趣。与其让这些任务在你的「已完成的任务」列表中占用空间，你可以让它们静默。要开始的话，在你的应用程序的 <code v-pre>horizon</code> 配置文件中的 <code v-pre>silenced</code> 配置选项中添加任务的类名：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token string single-quoted-string">'silenced'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Jobs<span class="token punctuation">\</span>ProcessPodcast</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>或者，你希望静默的任务可以实现 <code v-pre>Laravel\Horizon\Contracts\Silenced</code> 接口。如果一个任务实现了这个接口，即使它不在 <code v-pre>silenced</code> 配置数组中，它也将自动被静默：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Horizon<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Silenced</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">class</span> <span class="token class-name-definition class-name">ProcessPodcast</span> <span class="token keyword">implements</span> <span class="token class-name">ShouldQueue</span><span class="token punctuation">,</span> Silenced</span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">use</span> <span class="token package">Dispatchable</span><span class="token punctuation">,</span> InteractsWithQueue<span class="token punctuation">,</span> Queueable<span class="token punctuation">,</span> SerializesModels<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="升级-horizon" tabindex="-1"><a class="header-anchor" href="#升级-horizon"><span>升级 Horizon</span></a></h2>
<p>当你升级到 Horizon 的一个新的主要版本时，你需要仔细阅读<a href="https://github.com/laravel/horizon/blob/master/UPGRADE.md" target="_blank" rel="noopener noreferrer">升级指南</a>。</p>
<h2 id="运行-horizon" tabindex="-1"><a class="header-anchor" href="#运行-horizon"><span>运行 Horizon</span></a></h2>
<p>当在你的应用的 <code v-pre>config/horizon.php</code> 配置文件中配置了你的 supervisors 和 workers 之后，你可以使用 Artisan 命令 <code v-pre>horizon</code> 启动 Horizon。只需这一个命令你就可以启动为当前环境配置的所有 workers 进程：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你可以使用 Artisan 命令 <code v-pre>horizon:pause</code> 和 <code v-pre>horizon:continue</code> 来暂停和指示任务继续运行：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:pause</span>
<span class="line"></span>
<span class="line">php artisan horizon:continue</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以使用 <code v-pre>horizon:pause-supervisor</code> 和 <code v-pre>horizon:continue-supervisor</code> Artisan 命令暂停和继续指定的 Horizon <a href="#supervisors">supervisors</a>：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:pause-supervisor supervisor-1</span>
<span class="line"></span>
<span class="line">php artisan horizon:continue-supervisor supervisor-1</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以使用 Artisan 命令 <code v-pre>horizon:status</code> 检查 Horizon 进程的当前状态：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:status</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你可以使用 Artisan 命令 <code v-pre>horizon:terminate</code> 优雅地终止机器上的主 Horizon 进程。Horizon 会等当前正在处理的所有任务都完成后退出：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:terminate</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="部署-horizon" tabindex="-1"><a class="header-anchor" href="#部署-horizon"><span>部署 Horizon</span></a></h3>
<p>如果要将 Horizon 部署到一个正在运行的服务器上，应该配置一个进程监视器来监视 <code v-pre>php artisan horizon</code> 命令，并在它意外退出时重新启动它。别担心，我们接下来将讨论如何安装进程监视器。</p>
<p>在将新代码部署到服务器时，你需要指示 Horizon 终止主进程，以便进程监视器重新启动它并接收代码的更改：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:terminate</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="安装-supervisor" tabindex="-1"><a class="header-anchor" href="#安装-supervisor"><span>安装 Supervisor</span></a></h4>
<p>Supervisor 是一个用于 Linux 操作系统的进程监视器，如果 <code v-pre>Horizon</code> 进程被退出或终止，Supervisor 将自动重启你的 <code v-pre>Horizon</code> 进程。如果要在 Ubuntu 上安装 Supervisor，你可以使用以下命令。如果你不使用 Ubuntu，也可以使用操作系统的包管理器安装 Supervisor：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> supervisor</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>技巧</strong><br>
如果自己配置 Supervisor 听起来很麻烦，可以考虑使用 <a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a>，它将自动为你的 Laravel 项目安装和配置 Supervisor。</p>
</blockquote>
<h4 id="supervisor-配置" tabindex="-1"><a class="header-anchor" href="#supervisor-配置"><span>Supervisor 配置</span></a></h4>
<p>Supervisor 配置文件通常存储在 <code v-pre>/etc/supervisor/conf.d</code> 目录下。在此目录中，你可以创建任意数量的配置文件，这些配置文件会告诉 supervisor 如何监视你的进程。例如，让我们创建一个 <code v-pre>horizon.conf</code> 文件，它启动并监视一个 <code v-pre>horizon</code> 进程：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token section"><span class="token punctuation">[</span><span class="token section-name selector">program:horizon</span><span class="token punctuation">]</span></span></span>
<span class="line"><span class="token key attr-name">process_name</span><span class="token punctuation">=</span><span class="token value attr-value">%(program_name)s</span></span>
<span class="line"><span class="token key attr-name">command</span><span class="token punctuation">=</span><span class="token value attr-value">php /home/forge/example.com/artisan horizon</span></span>
<span class="line"><span class="token key attr-name">autostart</span><span class="token punctuation">=</span><span class="token value attr-value">true</span></span>
<span class="line"><span class="token key attr-name">autorestart</span><span class="token punctuation">=</span><span class="token value attr-value">true</span></span>
<span class="line"><span class="token key attr-name">user</span><span class="token punctuation">=</span><span class="token value attr-value">forge</span></span>
<span class="line"><span class="token key attr-name">redirect_stderr</span><span class="token punctuation">=</span><span class="token value attr-value">true</span></span>
<span class="line"><span class="token key attr-name">stdout_logfile</span><span class="token punctuation">=</span><span class="token value attr-value">/home/forge/example.com/horizon.log</span></span>
<span class="line"><span class="token key attr-name">stopwaitsecs</span><span class="token punctuation">=</span><span class="token value attr-value">3600</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在定义 Supervisor 配置时，你应该确保 <code v-pre>stopwaitsecs</code> 的值大于最长运行任务所消耗的秒数。否则，Supervisor 可能会在任务处理完之前就将其杀死。</p>
<blockquote>
<p><strong>注意</strong><br>
虽然上面的例子对基于 Ubuntu 的服务器有效，但其他服务器操作系统对 Supervisor 配置文件的位置和文件扩展名可能有所不同。请查阅你的服务器的文档以了解更多信息。</p>
</blockquote>
<h4 id="启动-supervisor" tabindex="-1"><a class="header-anchor" href="#启动-supervisor"><span>启动 Supervisor</span></a></h4>
<p>创建了配置文件后，可以使用以下命令更新 Supervisor 配置并启动进程：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">sudo</span> supervisorctl reread</span>
<span class="line"></span>
<span class="line"><span class="token function">sudo</span> supervisorctl update</span>
<span class="line"></span>
<span class="line"><span class="token function">sudo</span> supervisorctl start horizon</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>技巧</strong><br>
关于 Supervisor 的更多信息，可以查阅<a href="http://supervisord.org/index.html" target="_blank" rel="noopener noreferrer">Supervisor 文档</a>。</p>
</blockquote>
<h2 id="标签" tabindex="-1"><a class="header-anchor" href="#标签"><span>标签</span></a></h2>
<p>Horizon 允许你将「tags」分配给任务，包括邮件、事件广播、事件、通知和排队的事件监听器。实际上，Horizon 会智能且自动地标记大多数依赖 Eloquent 模型的任务。例如，看看下面的任务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Jobs</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>Video</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Bus<span class="token punctuation">\</span>Queueable</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Queue<span class="token punctuation">\</span>ShouldQueue</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Bus<span class="token punctuation">\</span>Dispatchable</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Queue<span class="token punctuation">\</span>InteractsWithQueue</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Queue<span class="token punctuation">\</span>SerializesModels</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">class</span> <span class="token class-name-definition class-name">RenderVideo</span> <span class="token keyword">implements</span> <span class="token class-name">ShouldQueue</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">use</span> <span class="token package">Dispatchable</span><span class="token punctuation">,</span> InteractsWithQueue<span class="token punctuation">,</span> Queueable<span class="token punctuation">,</span> SerializesModels<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token doc-comment comment">/**</span>
<span class="line">         * 创建一个新的任务实例。</span>
<span class="line">         */</span></span>
<span class="line">        <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">__construct</span><span class="token punctuation">(</span></span>
<span class="line">            <span class="token keyword">public</span> <span class="token class-name type-declaration">Video</span> <span class="token variable">$video</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">        <span class="token doc-comment comment">/**</span>
<span class="line">         * 执行任务。</span>
<span class="line">         */</span></span>
<span class="line">        <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">handle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token comment">// ...</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果此任务与 <code v-pre>App\Models\Video</code> 实例一起排队，且该实例的 <code v-pre>id</code> 为 <code v-pre>1</code>，则该任务将自动接收 <code v-pre>App\Models\Video:1</code> 标记。这是因为 Horizon 将为任何有 Eloquent 的模型检查任务的属性。如果找到了有 Eloquent 的模型，Horizon 将智能地使用模型的类名和主键标记任务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Jobs<span class="token punctuation">\</span>RenderVideo</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>Video</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$video</span> <span class="token operator">=</span> <span class="token class-name static-context">Video</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">RenderVideo</span><span class="token operator">::</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token variable">$video</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="手动标记任务" tabindex="-1"><a class="header-anchor" href="#手动标记任务"><span>手动标记任务</span></a></h4>
<p>如果你想手动定义你的一个队列对象的标签，你可以在类上定义一个 <code v-pre>tags</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token keyword">class</span> <span class="token class-name-definition class-name">RenderVideo</span> <span class="token keyword">implements</span> <span class="token class-name">ShouldQueue</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token doc-comment comment">/**</span>
<span class="line">         * 获取应该分配给任务的标签。</span>
<span class="line">         *</span>
<span class="line">         * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;int, string></span>
<span class="line">         */</span></span>
<span class="line">        <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">tags</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'render'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'video:'</span><span class="token operator">.</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">video</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="手动标记事件监听器" tabindex="-1"><a class="header-anchor" href="#手动标记事件监听器"><span>手动标记事件监听器</span></a></h4>
<p>当为时间监听器检索标签时，Horizon 将自动传递事件实例给 <code v-pre>tags</code> 方法，并允许你添加事件数据到标签：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token keyword">class</span> <span class="token class-name-definition class-name">SendRenderNotifications</span> <span class="token keyword">implements</span> <span class="token class-name">ShouldQueue</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token doc-comment comment">/**</span>
<span class="line">         * 获取要分配给事件监听器的标签。</span>
<span class="line">         *</span>
<span class="line">         * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;int, string></span>
<span class="line">         */</span></span>
<span class="line">        <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">tags</span><span class="token punctuation">(</span><span class="token class-name type-declaration">VideoRendered</span> <span class="token variable">$event</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'video:'</span><span class="token operator">.</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">video</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="通知" tabindex="-1"><a class="header-anchor" href="#通知"><span>通知</span></a></h2>
<blockquote>
<p><strong>注意</strong><br>
注意： 当配置 Horizon 发送 Slack 或 SMS 通知时，你应该查看<a href="https://learnku.com/docs/laravel/11.x/notificationsmd" target="_blank" rel="noopener noreferrer">相关通知驱动程序的先决条件</a>。</p>
</blockquote>
<p>如果你希望在一个队列有较长的等待时间时得到通知，你可以使用 <code v-pre>Horizon::routeMailNotificationsTo</code>, <code v-pre>Horizon::routeSlackNotificationsTo</code>, 和 <code v-pre>Horizon::routeSmsNotificationsTo</code> 方法。你可以通过应用程序的 <code v-pre>App\Providers\HorizonServiceProvider</code> 中的 <code v-pre>boot</code> 方法来调用这些方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 引导应用的一些服务。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token class-name static-context">Horizon</span><span class="token operator">::</span><span class="token function">routeSmsNotificationsTo</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'15556667777'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token class-name static-context">Horizon</span><span class="token operator">::</span><span class="token function">routeMailNotificationsTo</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'example@example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token class-name static-context">Horizon</span><span class="token operator">::</span><span class="token function">routeSlackNotificationsTo</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'slack-webhook-url'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'#channel'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="配置通知等待时间阈值" tabindex="-1"><a class="header-anchor" href="#配置通知等待时间阈值"><span>配置通知等待时间阈值</span></a></h4>
<p>你可以在 <code v-pre>config/horizon.php</code> 的配置文件中配置多少秒算是「长等待」。你可以用该文件中的 <code v-pre>waits</code> 配置选项控制每个 连接 / 队列 组合的长等待阈值。任何未定义 连接 / 队列 组合将默认 60 秒长等待阈值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token string single-quoted-string">'waits'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'redis:critical'</span> <span class="token operator">=></span> <span class="token number">30</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'redis:default'</span> <span class="token operator">=></span> <span class="token number">60</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'redis:batch'</span> <span class="token operator">=></span> <span class="token number">120</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="指标" tabindex="-1"><a class="header-anchor" href="#指标"><span>指标</span></a></h2>
<p>Horizon 有一个指标控制面板，它提供了任务和队列的等待时间和吞吐量等信息。要让这些信息显示在这个控制面板上，你应该在 <code v-pre>routes/console.php</code> 文件配置应用程序每五分钟运行一次 Horizon 的 Artisan 命令 <code v-pre>snapshot</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">    <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Schedule</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Schedule</span><span class="token operator">::</span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'horizon:snapshot'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">everyFiveMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="删除失败的任务" tabindex="-1"><a class="header-anchor" href="#删除失败的任务"><span>删除失败的任务</span></a></h2>
<p>如果你想删除失败的任务，可以使用 <code v-pre>horizon:forget</code> 命令。 <code v-pre>horizon:forget</code> 命令接受失败任务的 ID 或 UUID 作为其唯一参数：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:forget <span class="token number">5</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="从队列中清除任务" tabindex="-1"><a class="header-anchor" href="#从队列中清除任务"><span>从队列中清除任务</span></a></h2>
<p>如果你想从应用程序的默认队列中删除所有任务，你可以使用 Artisan 命令 <code v-pre>horizon:clear</code> 执行此操作：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:clear</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你可以设置 <code v-pre>queue</code> 选项来从特定队列中删除任务：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan horizon:clear <span class="token parameter variable">--queue</span><span class="token operator">=</span>emails</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/11.x/horizonmd/16721" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/ho...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/11.x/horizonmd/16721" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/ho...</a></p>
</blockquote>
</div></template>


